package com.pxample.pemo.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.*;

public class BaseController {

    private static ExecutorService exececutor;
    private static final int corePoolSize = 5;
    private static final int maximumPoolSize = 200;
    private static final int keepAliveTime = 10 * 1000;
    private static final int maxQueueTask = 5 * 1000;
    private static final long TIME_OUT = 10 * 1000;

    static {
        exececutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(maxQueueTask));
    }

    /**
     * @param servletRequest 请求
     * @param callable       业务
     * @desc 统一异步处理业务
     * @author gxing
     * @date 2022/7/30 16:35
     */
    public <T> void handler(HttpServletRequest servletRequest, Callable<T> callable) {
//        System.out.println("主线程开始:" + Thread.currentThread().getName() + ":" + DateUtil.format(new Date(), DateUtil.PATTERN_YMDHMS_SLASH));
        AsyncContext asyncContext = servletRequest.startAsync();
        asyncContext.setTimeout(TIME_OUT);
        asyncContext.addListener(new AsyncListener() {
            @Override
            public void onComplete(AsyncEvent event) throws IOException {

            }

            @Override
            public void onTimeout(AsyncEvent event) throws IOException {

            }

            @Override
            public void onError(AsyncEvent event) throws IOException {

            }

            @Override
            public void onStartAsync(AsyncEvent event) throws IOException {

            }
        });
        exececutor.execute(() -> {
//            System.out.println("异步线程开启:" + Thread.currentThread().getName());
            try {
//                Thread.sleep(5000);
                T result = callable.call();
                ServletResponse response = asyncContext.getResponse();
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter writer = response.getWriter();
                writer.println(JSONObject.toJSON(result));
            } catch (Exception e) {
                throw new RuntimeException(e);
            } finally {
                asyncContext.complete();
            }
//            System.out.println("异步线程结束:" + Thread.currentThread().getName());
        });
//        System.out.println("主线程结束:" + DateUtil.format(new Date(), DateUtil.PATTERN_YMDHMS_SLASH));
    }

}
